package com.mindbox.mueblesalpes.negocio.reportes;

import com.mindbox.mueblesalpes.negocio.entity.Cliente;
import com.mindbox.mueblesalpes.negocio.entity.Compra;
import com.mindbox.mueblesalpes.negocio.entity.MuebleInventario;
import com.mindbox.mueblesalpes.negocio.entity.MuebleReporte;
import com.mindbox.mueblesalpes.negocio.entity.TipoMueble;
import com.mindbox.mueblesalpes.negocio.entity.Ciudad;
import com.mindbox.mueblesalpes.negocio.entity.Mueble;
import com.mindbox.mueblesalpes.negocio.entity.Venta;
import com.mindbox.mueblesalpes.negocio.exception.TiendaException;
import com.mindbox.mueblesalpes.negocio.persistence.PersistenciaLocal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Jaimoto
 */
@Stateless
@DeclareRoles({"Administrador", "Gerente"})
public class ReportesEJB implements IReportes {

    @PersistenceContext
    EntityManager em;

    @EJB
    PersistenciaLocal persistenciaService;

    /**
     *
     */
    public ReportesEJB() {

    }

    /**
     *
     */
    @PostConstruct
    public void init() {

    }


    
    @Override
    @RolesAllowed({"Gerente"})
    public ReporteVenta generarReporteVentas(Date fechaIni, Date fechaFin, Ciudad ciudad) throws Exception {
        try {
            ReporteVenta rep = new ReporteVenta();
            ciudad = (Ciudad) persistenciaService.findById(Ciudad.class, ciudad.getIdCiudad());
            rep.setCiudad(ciudad);
            rep.setFechaIni(fechaIni);
            rep.setFechaFin(fechaFin);
            rep.setFechaReporte(new Date());
            List<MuebleInventario> interior = new ArrayList();
            List<MuebleInventario> exterior = new ArrayList();
            String txtQuery = "SELECT c from Compra c where c.venta.cliente.ciudadResidencia.idCiudad = :ciudad and c.venta.fecha between :fecha1 and :fecha2";
            Query query = em.createQuery(txtQuery);
            query.setParameter("ciudad", ciudad.getIdCiudad());
            query.setParameter("fecha1", fechaIni);
            query.setParameter("fecha2", fechaFin);
            List<Compra> aux = query.getResultList();
            for (Compra compra : aux) {
                //System.out.println(compra.getVenta().getCliente().getCiudadResidencia().getNombre() + " | " + compra.getMueble().getTipoMueble() + " | " + compra.getMueble().getNombre());
                MuebleInventario muebleInventario = new MuebleInventario();
                muebleInventario.setPrecio(compra.getPrecio());
                muebleInventario.setCantidad(compra.getCantidad());
                muebleInventario.setMueble(compra.getMueble());
                if(compra.getMueble().getTipoMueble().equals(TipoMueble.EXTERIOR)){
                    exterior.add(muebleInventario);
                    rep.setTotalExterior(rep.getTotalExterior()+compra.getPrecio());
                }else{
                    interior.add(muebleInventario);
                    rep.setTotalInterior(rep.getTotalInterior()+compra.getPrecio());
                }
            }
            rep.setListExterior(exterior);
            rep.setListInterior(interior);

            return rep;
        } catch (Exception e) {
            e.printStackTrace();
            throw new TiendaException("Se produjo un error al generar el reporte ");
        }
    }


    @Override
    @RolesAllowed({"Gerente"})
    public ReporteTop generarReporteProductoTop(Date fechaIni, Date fechaFin, Ciudad ciudad, int cantidad) throws Exception {
        try {
            ReporteTop rep = new ReporteTop();
            ciudad = (Ciudad) persistenciaService.findById(Ciudad.class, ciudad.getIdCiudad());
            rep.setCiudad(ciudad);
            rep.setFechaIni(fechaIni);
            rep.setFechaFin(fechaFin);
            rep.setFechaReporte(new Date());
            List muebles = new ArrayList();
            String txtQuery = "SELECT sum(c.precio),sum(c.cantidad) ,c.mueble.referencia from Compra c where c.venta.cliente.ciudadResidencia.idCiudad = :ciudad and c.venta.fecha between :fecha1 and :fecha2 group by c.mueble.referencia ";
            Query query = em.createQuery(txtQuery);
            query.setParameter("ciudad", ciudad.getIdCiudad());
            query.setParameter("fecha1", fechaIni);
            query.setParameter("fecha2", fechaFin);
            List<Object[]> aux = query.getResultList();
            for (Object[] compra : aux) {
                Mueble mueble = (Mueble) persistenciaService.findById(Mueble.class, compra[2]);
                MuebleReporte muebleReporte = new MuebleReporte();
                /*muebleReporte.setPrecio(compra.getPrecio());
                muebleReporte.setCantidad(compra.getCantidad());*/
                muebleReporte.setCiudad(ciudad);
                muebleReporte.setMueble(mueble);
                muebles.add(muebleReporte);
            }
            rep.setListMuebles(muebles);
            return rep;
        } catch (Exception e) {
            e.printStackTrace();
            throw new TiendaException("Se produjo un error al generar el reporte ");
        }
    }


    @Override
    @RolesAllowed({"Gerente"})
    public ReporteCompras generarReporteCompras(Cliente cliente, Date fechaIni, Date fechaFin, Ciudad ciudad) throws Exception {
        ReporteCompras rep = new ReporteCompras();
        try {
            rep.setCiudad(ciudad);
            rep.setFechaIni(fechaIni);
            rep.setFechaFin(fechaFin);
            rep.setFechaReporte(new Date());
            String txtQuery = "SELECT v from Venta v where v.cliente.idCliente = :cliente and v.fecha between :fecha1 and :fecha2 ";
            Query query = em.createQuery(txtQuery);
            query.setParameter("cliente", cliente.getIdCliente());
            query.setParameter("fecha1", fechaIni);
            query.setParameter("fecha2", fechaFin);
            List<Venta> aux = query.getResultList();
            rep.setListCompras(aux);
            return rep;
        } catch (Exception e) {
            e.printStackTrace();
            throw new TiendaException("Se produjo un error al generar el reporte ");
        }


        
       
        

    }

}

